package net.bat.servlet;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Vector;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.hibernate.metadata.ClassMetadata;
import org.jabsorb.JSONSerializer;
import org.jabsorb.serializer.MarshallException;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import dao.hb.NSort;
import dao.hb.UUser;
import net.bat.db.BaseDAOImpl;
import net.bat.upload.uploadServlet;
import net.bat.util.Cfg;
import net.cs.um.UMService;


class Node{
	int id;
	String text;
	boolean leaf;
	Node[] children=null;
	boolean checked = false;
	
	ArrayList<Node> clist=new ArrayList<Node>();
	Node(int id,String text){
		this.id=id;
		this.text = text;
	}
	void addNode(Node nd){
		clist.add(nd);
	}
	void update(){
		int len =clist.size();
		if(len==0){
			leaf = true;
		}else{
			//TODO 按ord排序
			leaf=false;
			children = new Node[len];
			for(int i=0; i<len; i++){
				Node cn = clist.get(i);
				cn.update();
				children[i]=cn;
			}
		}
	}
	Node[] getChildren(){
		return children;
	}
}
public class MbJSonBaseServlet extends HttpServlet {
	/**
	 * 
	 */
	static public String SPLIT_LANG_COUNTRY = "-";
	private static final long serialVersionUID = 1L;
	private BaseDAOImpl dao=null;
	private JSONSerializer ser;
	private HashMap<String,String> ls_map;

	public BaseDAOImpl getDao() {
		if(dao==null)
			dao = (BaseDAOImpl)Cfg.getBean("BaseDAOImpl");
		return dao;
	}
	public void setDao(BaseDAOImpl dao) {
		this.dao = dao;
	} 	 
    public void init() throws ServletException {
    	ls_map = new HashMap<String,String>();
    	ser = new JSONSerializer();
    	try {
			ser.registerDefaultSerializers();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
    public void putJSon(String hql,String jsonStr){
    	ls_map.put(hql, jsonStr);
    }
    public String getJSon(String hql){
    	return ls_map.get(hql);
    }
    public String getJTType(String tn,Integer rid){
    	List ls = getDao().find("from "+tn);
		HashMap<Integer,Node> nodeMap = new HashMap<Integer,Node>();
		int len_ls=ls.size();
		for(int i=0; i<len_ls; i++){
			Object ns = ls.get(i);
			BeanWrapper bw = new BeanWrapperImpl(ns);
			Integer id = (Integer)bw.getPropertyValue("id");
			String name = (String)bw.getPropertyValue("mc");
			nodeMap.put(id, new Node(id,name));
		}
		Node root = new Node(0,"root");
		for(int i=0; i<len_ls; i++){
			Object ns = ls.get(i);
			BeanWrapper bw = new BeanWrapperImpl(ns);
			Integer pid = (Integer)bw.getPropertyValue("sj");
			Integer id = (Integer)bw.getPropertyValue("id");
			Node nd = nodeMap.get(id);
			if(pid!=null){
				nodeMap.get(pid).addNode(nd);
			}else{
				root.addNode(nd);
			}
		}
		root.update();
		Gson gson=new GsonBuilder().setPrettyPrinting().create();
		if(rid!=null){
			root = nodeMap.get(rid);
		}
		String jstr = gson.toJson(root.getChildren());
    	return jstr;

    }
    private List<String[]> listLang(String lang){
		Vector<String[]> rl = new Vector<String[]>();
		Locale[] localeList = Locale.getAvailableLocales();
		String[] lc = lang.split(SPLIT_LANG_COUNTRY);
		Locale loc_lang;
		if(lc.length==1)
			loc_lang= new Locale(lang);
		else{
			loc_lang=new Locale(lc[0],lc[1]);
		}
		for(int i=0; i<localeList.length; i++) {
			Locale cur = localeList[i];
			String disc=cur.getDisplayCountry(loc_lang);
			if(disc==null || disc.trim().equals("")){
				continue;
			}
			rl.add(new String[]{cur.getLanguage()+SPLIT_LANG_COUNTRY+cur.getCountry(),
					disc+SPLIT_LANG_COUNTRY+cur.getDisplayLanguage(loc_lang)});
		}
    	return rl;
    }
    @SuppressWarnings("rawtypes")
	private List listEntitys() {		
		org.hibernate.SessionFactory sf = getDao().getSessionFactory();
		Map map = sf.getAllClassMetadata();
		Iterator it = map.entrySet().iterator();  //所有类名
		Vector<String[]> rl = new Vector<String[]>();
		rl.add(new String[]{"无","无"});
		rl.add(new String[]{"全部","全部"});
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			String key_en = (String) entry.getKey();
			rl.add(new String[]{key_en,key_en});
		}
		return rl;
	}
    private String toJSON(Object o){
    	try {
			return ser.toJSON(o);
		} catch (MarshallException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
    }
    public String getJSonTree(String nid){
		List ls = getDao().find("from NSort where nid="+nid);
		HashMap<Integer,Node> nodeMap = new HashMap<Integer,Node>();
		int len_ls=ls.size();
		for(int i=0; i<len_ls; i++){
			NSort ns = (NSort)ls.get(i);
			nodeMap.put(ns.getId(), new Node(ns.getId(),ns.getTitle()));
		}
		Node root = new Node(0,"root");
		for(int i=0; i<len_ls; i++){
			NSort ns = (NSort)ls.get(i);
			Integer pid = ns.getPid();
			int id = ns.getId();
			Node nd = nodeMap.get(id);
			if(pid!=null){
				nodeMap.get(pid).addNode(nd);
			}else{
				root.addNode(nd);
			}
		}
		root.update();
		Gson gson=new GsonBuilder().setPrettyPrinting().create();
		String jstr = gson.toJson(root.getChildren());
    	return jstr;
    }
    
    /**
     * hql=select userId,userId from UUser'
     * @param hql
     * @return
     */
    private String appendQuery(String hql,String query){
    	if(query==null || query.isEmpty()) {
			return hql;
		}
    	String rhql;
    	String lhql = hql.toLowerCase();
    	int pos_from = lhql.indexOf("from");
    	int pos_select = lhql.indexOf("select");
    	int pos_where = lhql.indexOf("where");
    	String fldstr = hql.substring(pos_select+7, pos_from);
    	String[] flds=fldstr.split(",");
    	String qstr="";
    	for(int i=0; i<flds.length; i++){
    		if(i==0) {
				qstr = flds[i]+" like "+" '"+query+"%'";
			} else {
				qstr+=" or "+flds[i]+" like "+" '"+query+"%'";
			}
    	}
    	if(pos_where==-1){
    		rhql = hql+" where ("+qstr+")";
    	}else{
    		rhql = hql+" and ("+qstr+")";
    	}
    	return rhql;
    }
    
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String query = request.getParameter("query");
		String nid = request.getParameter("nid");
		
		//01.13  add
		String value=request.getParameter("value");
		
		if(value!=null){
			String hql=request.getParameter("hql");
			UUser us=(UUser)dao.find(hql);
		    int uid=us.getId();
			
		//    String bxhq="from BxSimplerecord where uid"
			return;
		}
		
		//===============
		
		String out;
		if(nid!=null){
			response.getOutputStream().write(getJSonTree(nid).getBytes("utf-8"));		
			return;
		}
		String tn = request.getParameter("tn");
		if(tn!=null){
			Integer rid = null;
			String sid = request.getParameter("rid");
			if(sid!=null){
				rid = Integer.parseInt(sid);
			}
			response.getOutputStream().write(getJTType(tn,rid).getBytes("utf-8"));		
			return;
		}
		List ls;
		String hql = request.getParameter("hql");
		if(hql.equals("LIST_ENTITYS")){
			//对数据库表列表进行缓存
			out = getJSon(hql);
			if(out==null){
				ls = listEntitys();
				out =toJSON(ls);
				putJSon(hql,out);
			}
		}else if(hql.equals("LIST_LANG_")){
			String lang=null;
			try {
			  UUser usr = UMService.getUserBySession(request);
			  lang = usr.getLang();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if(lang==null){
				Locale loc=Locale.getDefault();
				lang=loc.getLanguage()+SPLIT_LANG_COUNTRY+loc.getCountry();
			}
			String key =hql+lang;
			out = getJSon(key);
			if(out==null){
				ls = listLang(lang);
				out =toJSON(ls);
				putJSon(key,out);
			}
		}
		else{
			ls = getDao().find(appendQuery(hql,query));
			out =toJSON(ls);
		}
		response.getOutputStream().write(out.getBytes("utf-8"));		
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request,response);
	}

}
